package com.gitee.wsl.compose.ui.toast


import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.vector.ImageVector
import com.gitee.wsl.compose.ui.base.Toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock


@Stable
class ToastUIState {
    private val mutex = Mutex()

     var currentData: ToastData? by mutableStateOf(null)
        private set

     suspend fun show(
        message: String,
        icon: ImageVector? = null,
    ): Unit = mutex.withLock {
        try {
            return suspendCancellableCoroutine { cont ->
                currentData = ToastDataImpl(
                    message,
                    icon,
                    cont,
                )
            }
        } finally {
            currentData = null
        }
    }

    suspend fun show(
        toastModel: ToastModel
    ): Unit = mutex.withLock {
        try {
            return suspendCancellableCoroutine { cont ->
                currentData = ToastDataImpl(
                    toastModel.message,
                    null,
                    cont,
                    toastModel.type,
                    toastModel.durationTime
                )
            }
        } finally {
            currentData = null
        }
    }

}


val LocalToastUIState: ProvidableCompositionLocal<ToastUIState> = staticCompositionLocalOf {
    ToastUIState()
}

@Composable
fun Toast.Toast(
    message: String,
    icon: ImageVector? = null,
    scope:CoroutineScope = rememberCoroutineScope()
) {
    val state = LocalToastUIState.current
    scope.launch {
        state.show(message, icon)
    }
}


@Composable
fun Toast.Error(
    message: String,
    scope:CoroutineScope = rememberCoroutineScope()
) {
    val state = LocalToastUIState.current
    scope.launch {
        state.show(ToastModel.Error(message))
    }
}


@Composable
fun Toast.Warning(
    message: String,
    scope:CoroutineScope = rememberCoroutineScope()
) {
    val state = LocalToastUIState.current
    scope.launch {
        state.show(ToastModel.Warning(message))
    }
}


@Composable
fun Toast.Success(
    message: String,
    scope:CoroutineScope = rememberCoroutineScope()
) {
    val state = LocalToastUIState.current
    scope.launch {
        state.show(ToastModel.Success(message))
    }
}


@Composable
fun Toast.Info(
    message: String,
    scope:CoroutineScope = rememberCoroutineScope()
) {
    val state = LocalToastUIState.current
    scope.launch {
        state.show(ToastModel.Info(message))
    }
}